package com.xunxi.mimi.ui.base;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import com.readystatesoftware.systembartint.SystemBarTintManager;
import com.xunxi.mimi.app_base.R;
import com.xunxi.mimi.constants.EventBusCode;
import com.xunxi.mimi.ui.dialog.LoadingDialog;
import com.xunxi.mimi.ui.statusbar.ImmersionBar;
import com.xunxi.mimi.utils.AppUtils;

import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent;
import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEventListener;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.List;

import butterknife.ButterKnife;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;


/**
 * activity基类
 * liyu
 */
public abstract class BaseActivity extends AppCompatActivity {

    protected String TAG = getClass().getName();

    private SystemBarTintManager tintManager;

    private ImmersionBar mImmersionBar;

    private LoadingDialog mLoadingDialog;

    private CompositeDisposable mCompositeDisposable;//rx管理器，用来取消订阅

    /**
     * 是否允许沉浸式
     */
    private boolean mEnableStatusBar = true;

    private AudioManager mAudioManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        overridePendingTransition(getActivityInAnim(), R.anim.live_no_anim);
        this.onCreate(savedInstanceState, TAG);

        ButterKnife.bind(this);

        this.initBack();
        this.initStatusBar();
        this.initPresenter();
        this.initView();
        this.initValue();

        //注册EventBus通信
        EventBus.getDefault().register(this);
        ActManager.getAppManager().addActivity(this);
    }

    /**
     * 程序执行入口 调用完Activity.onCreate之后马上调用
     *
     * @param savedInstanceState
     * @param tag
     */
    protected abstract void onCreate(Bundle savedInstanceState, String tag);

    protected abstract void initView();

    protected abstract void initPresenter();

    protected abstract void initValue();

    protected void onRequestAudioFocus() {
        if (mAudioManager == null) {
            mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        }
        mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
    }

    /**
     * Desc:释放音频焦点
     * <p>
     * Author: [李豫]
     * Date: 2019-01-14
     */
    protected void onReleaseAudioFocus() {
        if (mAudioManager != null) {//获取声音焦点
            mAudioManager.abandonAudioFocus(null);
        }
    }

    @Override
    public void finish() {
        super.finish();
//        overridePendingTransition(R.anim.live_no_anim, getActivityOutAnim());
        ActManager.getAppManager().finishActivity(this);
    }

    public void setEnableStatusBar(boolean isAble) {
        mEnableStatusBar = isAble;
    }

    private void initBack() {
        View back = findViewById(R.id.btn_back);
        if (back != null) {
            back.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });
        }
    }

    private void initStatusBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (mEnableStatusBar) {
                setTranslucentStatus(true);
            }
        }

        tintManager = new SystemBarTintManager(this);
        if (mEnableStatusBar) {
            tintManager.setStatusBarTintEnabled(true);
            tintManager.setNavigationBarTintEnabled(false);
            tintManager.setStatusBarTintResource(R.color.colorPrimaryDark);

            initStatusBarTextColor();
        }
    }

    private void initStatusBarTextColor() {
        mImmersionBar = ImmersionBar.with(this);
        mImmersionBar.statusBarColor(android.R.color.transparent)
                .statusBarDarkFont(false, 0.2f)
                .init();
    }

    public void setStatusBarTextColorWhite() {
        if (mImmersionBar != null) {
            mImmersionBar.statusBarDarkFont(false).init();
        }
    }

    public void setStatusBarTextColorDark() {
        if (mImmersionBar != null) {
            mImmersionBar.statusBarDarkFont(true, 0.2f).init();
        }
    }

    public void setStatusBarTintResource(int colorRes) {
        if (tintManager != null) {
            tintManager.setTintResource(colorRes);
//            tintManager.setStatusBarTintResource(colorRes);
        }
    }

    public void setStatusBarTintColor(int color) {
        if (tintManager != null) {
            tintManager.setTintColor(color);
//            tintManager.setStatusBarTintResource(colorRes);
        }
    }

    @TargetApi(19)
    private void setTranslucentStatus(boolean on) {
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }

    /**
     * 隐藏进度条
     */
    public void dismissLoadingDialog() {
        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
            mLoadingDialog.dismiss();
        }
    }

    /**
     * 显示进度条
     */
    public void showLoadingDialog() {
        if (mLoadingDialog == null) {
            mLoadingDialog = new LoadingDialog(this);
        }
        mLoadingDialog.show();
    }

    /**
     * 启动页面跳转
     *
     * @param cls cls
     */
    public void startIntent(Class<?> cls) {
        this.startIntent(this, cls);
    }

    /**
     * 启动页面跳转
     *
     * @param cls cls
     */
    public void startIntent(Class<?> cls, Bundle bundle) {
        this.startIntent(this, cls, bundle);
    }

    /**
     * 启动页面跳转
     *
     * @param context 上下文对象
     * @param cls     cls
     */
    public void startIntent(Context context, Class<?> cls) {
        this.startIntent(context, cls, null);
    }

    /**
     * 启动页面跳转
     *
     * @param context 上下文对象
     * @param cls     cls
     * @param bundle  数据集
     */
    public void startIntent(Context context, Class<?> cls, Bundle bundle) {
        Intent intent = new Intent(context, cls);

        if (bundle != null) {
            intent.putExtras(bundle);
        }

        context.startActivity(intent);
    }

    public void startIntentAndFinish(Class<?> cls) {
        Intent intent = new Intent(this, cls);
        startActivity(intent);
        finish();
    }

    /**
     * 启动页面跳转 附带返回
     *
     * @param cls         cls
     * @param requestCode 请求code
     */
    public void startActivityForResult(Class<?> cls, int requestCode) {
        Intent intent = new Intent(this, cls);
        startActivityForResult(intent, requestCode);
    }

    /**
     * 启动页面跳转 附带返回
     *
     * @param cls         cls
     * @param bundle      数据集
     * @param requestCode 请求code
     */
    public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
        Intent intent = new Intent(this, cls);
        intent.putExtras(bundle);
        startActivityForResult(intent, requestCode);
    }

    /**
     * eventBus可以重写，用来处理接收消息，
     *
     * @param event
     */
    @Subscribe
    public void onEventMainThread(Object event) {
        if (event instanceof Bundle) {
            int eventCode = ((Bundle) event).getInt(EventBusCode.EVENT_BUS_CODE);
            onEventMainThread(eventCode, (Bundle) event);
        }
    }

    /**
     * eventBus可以重写，用来处理接收消息，
     *
     * @param eventCode
     */
    public void onEventMainThread(int eventCode, Bundle bundle) {
    }

    protected void unSubscribe() {
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
        }
    }

    protected void addSubscribe(Disposable subscription) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(subscription);
    }

    @Override
    protected void onDestroy() {
        unSubscribe();
        //注销EventBus
        EventBus.getDefault().unregister(this);
        if (mImmersionBar != null) {
            mImmersionBar.destroy();
        }
        super.onDestroy();
    }

    /**
     * 软键盘状态
     */
    private boolean mKeyboardOpened;

    /**
     * 在initViews里使用
     * 启用软键盘状态监听
     */
    protected void enableKeyboardVisibilityHandle() {
        KeyboardVisibilityEvent.setEventListener(this, new KeyboardVisibilityEventListener() {
            @Override
            public void onVisibilityChanged(boolean isOpen) {
                mKeyboardOpened = isOpen;
                onKeyboardVisibilityChanged(isOpen);
                List<Fragment> fragments = getSupportFragmentManager().getFragments();
                if (fragments != null && fragments.size() > 0) {
                    for (Fragment f : fragments) {
                        if (f instanceof BaseFragment) {
                            BaseFragment base = (BaseFragment) f;
                            if (base.isHandleKeyboardVisible()) {
                                base.onKeyboardVisibilityChanged(isOpen);
                            }
                        }
                    }
                }
            }
        });
    }

    /**
     * 判断软键盘是否打开
     *
     * @return
     */
    public boolean isKeyboardOpened() {
        return mKeyboardOpened;
    }

    /**
     * 处理软键盘的打开/关闭
     *
     * @param visibility
     */
    protected void onKeyboardVisibilityChanged(boolean visibility) {

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mKeyboardOpened && ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if (dispatchClickView((ViewGroup) findViewById(android.R.id.content), ev))
                return super.dispatchTouchEvent(ev);
            if (v != null) {
                View parent = (View) v.getParent();
                String tag = (String) parent.getTag();
                if (tag != null && tag.equals("input")) {
                    v = parent;
                }
            }
            if (isShouldHideKeyboard(v, ev)) {
                AppUtils.hideIme(this);
                return true;
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    private boolean dispatchClickView(ViewGroup contentView, MotionEvent event) {
        boolean isDispatch = false;
        for (int i = contentView.getChildCount() - 1; i >= 0; i--) {
            View childView = contentView.getChildAt(i);
            boolean touchView = isTouch(event, childView);
            if (!childView.isShown()) {
                continue;
            }
            if (touchView && "dispatch".equals(childView.getTag())) {
                isDispatch = true;
                break;
            }
            if (childView instanceof ViewGroup) {
                ViewGroup itemView = (ViewGroup) childView;
                if (!touchView) {
                    continue;
                } else {
                    isDispatch |= dispatchClickView(itemView, event);
                    break;
                }
            }
        }
        return isDispatch;
    }

    private boolean isTouch(MotionEvent event, View view) {
        Rect rect = new Rect();
        view.getGlobalVisibleRect(rect);
        return rect.contains((int) event.getX(), (int) event.getY());
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null) {
            Rect rect = new Rect();
            v.getGlobalVisibleRect(rect);
            return !rect.contains((int) event.getX(), (int) event.getY());
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditText上，和用户用轨迹球选择其他的焦点
        return false;
    }
}
